 /**
* 
* 就一个容器，提供在追加和删除元素，注意删除之后其他都要上移，弄完了要马上做实验测试
*
*滚到那里都是要听sliderbar的命令
* 
* 注意这个里面存储是视图,不要用这个来管理逻辑！吃过这个亏的~
* 
* --
* 这个不要控制逻辑，只控制视图，不核心的去维持数据，就是把很多条目滚动显示即可
* 
* 结构是一个spr_c承载spr_map和sb
* 
*标准的SmartList,很标准的 
*
*var sb:SmartSliderBarV=new SmartSliderBarV(Util.AttachMC("MyMc_SliderBar"), height);
		var smartList:SmartList=new SmartList(width,height, sb, itemHeight);
		smartList.clear();
		return smartList;
*/
package kgame5.kgui.kcomp {
import gs.TweenLite;

import kgame5.kmath.MathDG;
import kgame5.kutil.*;

import flash.display.*;
import flash.events.*;
import flash.geom.*;

public class SmartList{
	
	private static const DUR:Number=0.5;//条目运动的时间0.3秒
	
	//____________________Property_____________________
	
	//--数据模型
	private var aItem : Array = null;//注意！！因为是Array,所以能容纳各种类型
	
	//--视图模块
	private var 
		spr_c:Sprite=null,//整个的对外的
			spr_map:Sprite=null;//--装载地图的
	
	//--
	private var rect:Rectangle;
	
	private var mapH:Number;
	
	private var sb:SmartSliderBar;
	
	private var DefaultElemH:Number=-1;//默认的每个条目的高度,这个是说在addItem()里不明确指明每个条目的高度
	
	//____________________Method_____________________
	public function SmartList (EW:Number, EH : Number,p_sb:SmartSliderBar,p_DefaultElemH:Number=20){
		//
		aItem = new Array ();
		
		DefaultElemH=p_DefaultElemH;//如果在addItem的时候没有明确指出ElemH,则使用这个作为默认的
		
		//
		rect=new Rectangle(0,0,EW,EH);
		
		//--
		spr_c= new Sprite();;
		
			//-
			spr_map=new Sprite();
			spr_c.addChild(spr_map);
			
			//-
			sb=p_sb;
			spr_c.addChild(sb.getDO());

			//设置bar的长度和sb.btn2的位置
			sb.getDO().x=rect.width-sb.getDO().width/2;//sliderbar的位置靠在最右边
		
		//注册当sliderBar滚动的时候我才滚动
		sb.addEventListener(SmartSliderBar.EVENTTYPE_SLIDERMOVE,OnSliderBarMove,false,0,true);
		
		//--
		clear();
	}
	//当得到sliderBar移动的时候移动
	private function OnSliderBarMove(e:Event){
		///-rect.y=(mapH - rect.height) * sb.getPercent();
		rect.y=mapH * sb.getPercent();
		//--限制好边界
		var bottom:int=mapH-rect.height;//rectY移动的最下面的边界
		if(bottom<0){
			bottom=0;
		}
		rect.y=MathDG.C(rect.y,0,bottom);
		
		//--
		spr_map.scrollRect=rect;
	}
	//---删除所有的elem,这个用来初始化
	public function clear (){
		//T.p("smartList.clear");
		//Step 1: 删除其中装载的mc_item
		var i:int;
		var len:int=size();
		for(i=0;i<len;i++){
			var mc : MovieClip =getItemAt(i);
			spr_map.removeChild(mc);
		}
		//Step 2: 释放数组
		aItem = new Array ();
		//Step3:视野部分初始化区域
		mapH = 0;
		focusAimY=0;
		
		//rect.x=0;
		rect.y=0;
		spr_map.scrollRect=rect;
		
		//--Step 4,自己的滚动条位置也要清零的
		sb.clear();
		
		//--Step 5,测试是否显示sb
		testShowSB();
	}
	public function getDO():DisplayObject{
		return spr_c;
	}
	
	//
	public function size () : int{
		return aItem.length;
	}
	
	//这个是用来读取和返回ItemHeight用的
	public static function SetItemHeight(mc:MovieClip,ItemHeight:Number){
		mc.ItemHeight=ItemHeight;
	}
	public static function GetItemHeight(mc:MovieClip):Number{
		return mc.ItemHeight;
	}
	
	//注意这个弄完了要重新设置焦点的
	public function changeItemHeight(mc:MovieClip,p_ItemHeight:Number){
		T.p("changeItemHeight",mc.ItemHeight,p_ItemHeight);
		
		var preP:Number=sb.getPercent();//~更新sb的滚动条
		
		var sub:Number=p_ItemHeight-GetItemHeight(mc);
		
		SetItemHeight(mc,p_ItemHeight);
		
		//1:找到目标
		var k:int=contains(mc);
		if (k == - 1){
			//T.p ("没找到要删除的这个");
			return;
		}
		
		
		//2:其他东西上移
		var i:int;
		var len:int=size();
		
		for (i = k + 1; i < len; i ++){
			var mc : MovieClip = getItemAt(i);
			
			var aimY:Number=getItemY(i);
			//Tween2DX.StartMoveY(mc,aimY,DUR);//平滑移动到目标
			TweenLite.to(mc,DUR,{y:aimY});
		}
		
		mapH+=sub;
		
		//--Step 5,测试是否显示sb
		testShowSB();
		
		//--更新sb的滚动条
		sb.changeSliderHeight(rect.height, mapH,aItem);
		sb.setPercent(preP);
	}
	//注意在addItem之前要设置好Item的Height和width
	public function addItem (mc:MovieClip,ItemHeight:Number=-1){
		//T.p("sl.addItem");
		var preP:Number=sb.getPercent();//~更新sb的滚动条
		
		//如果没有明确指出高度，则使用默认的高度
		if(ItemHeight==-1){
			ItemHeight=DefaultElemH;
		}
		
		SetItemHeight(mc,ItemHeight);
		//--
		spr_map.addChild(mc);
		
		//--数据模型,在队列里加上
		aItem.push (mc);
		
		//--出现的动画
		mc.y=rect.y;//这个从当前可视区域的上面出现,保证不会因为太多的Item而导致条目出现问题
		var aimY:Number=mapH;
		//Tween2DX.StartMoveY(mc, aimY, DUR);//平滑移动到目标
		TweenLite.to(mc,DUR,{y:aimY});
		//mc.alpha=0;
		//Tween2DX.StartFade(mc,1,DUR);//淡入,这个加上就有问题
		
		//--调整slider的长度,
		mapH +=GetItemHeight(mc);
		
		//--照样显示的是焦点
		setFocusAimY(focusAimY);
		
		//--Step 5,测试是否显示sb
		testShowSB();
		
		//--更新sb的滚动条
		sb.changeSliderHeight(rect.height, mapH,aItem);
		sb.setPercent(preP);
	}
	

	//
	public function removeItem (mc_aim:MovieClip){
		//--------视图操作---------
		var preP:Number=sb.getPercent();//~更新sb的滚动条
		
		//1:找到目标
		var k:int=contains(mc_aim);
		if (k == - 1){
			//T.p ("没找到要删除的这个");
			return;
		}
		
		var ItemHeight:int=GetItemHeight(mc_aim);//要删除的的东西的高度
		
		//2:其他东西上移
		var i:int;
		var len:int=size();
		
		for (i = k + 1; i < len; i ++){
			var mc : MovieClip = getItemAt(i);
			
			var aimY:Number=getItemY(i)-ItemHeight;
			//Tween2DX.StartMoveY(mc,aimY,DUR);//平滑移动到目标
			TweenLite.to(mc,DUR,{y:aimY});
		}
		//3:删除目标
		spr_map.removeChild(mc_aim);
		//4:地图高度减小,调整slider的长度
		mapH -= ItemHeight;
		
		//--照样显示的是焦点
		setFocusAimY(focusAimY);
		
		//5,数据模型操作
		aItem.splice(k,1);
		
		//--Step 5,测试是否显示sb
		testShowSB();
		
		//--更新sb的滚动条
		sb.changeSliderHeight(rect.height, mapH,aItem);
		sb.setPercent(preP);
	}
	// 取得指定索引的elem的Y
	private function getItemY(idx:int):Number{
		var itemY:Number=0;
		for(var i:int=0;i<idx;i++){
			itemY+=GetItemHeight(getItemAt(i));
		}
		return itemY;
	}
	//
	public function getItemAt(i : int):MovieClip{
		var o:MovieClip=aItem [i];
		
		return o;
	}
	//
	public function contains(mc_item:MovieClip):int{
		var i:int;
		var len:int=size();
		for(i=0;i<len;i++){
			if(aItem[i]==mc_item){
				//T.p("smartList.contains"+i);
				return i;
			}
		}
		return -1;
	}
	
	//p_aimY是指的地图视窗的中心,这个是命令eyeshot移动到让焦点位置居中
	private var focusAimY:Number=0;//这个保存为的是
	public function setFocusAimY (aimY : Number){
		//T.p("setFocusAimY:"+aimY);
		
		/*
		focusAimY=aimY;
		focusAimY=MathDG.C(focusAimY, 0, mapH - rect.height/2);
		
		var h:Number=(mapH - rect.height);
		h=MathDG.C(h, rect.height,h);
		var ey:Number=(focusAimY - rect.height /2);
		ey=MathDG.C(ey, 0, h);
		
		sb.setPercent(ey/h);
		//*/
		
		focusAimY=aimY - rect.height/2;
		focusAimY=MathDG.C(focusAimY, 0, mapH - rect.height);
		
		
		
		sb.setPercent(focusAimY/mapH);
	}
	
	//
	public function setFocusByIdx(idx:int){
		setFocusAimY(getItemY(idx)+GetItemHeight(getItemAt(idx))/2);
	}
	//这个是需要索引的
	public function setFocusByItem(mc_item:MovieClip){
		var idx:int=contains(mc_item);
		T.p(idx);
		if(idx!=-1){
			setFocusByIdx(idx);
		}
	}
	
	//-----------这个是对外部的滚动按钮的控制
	private var ScrollSpeed:Number=3;
	private var iCurScrollSpeed:Number=0;
	private var 
		mc_arrowUp:MovieClip,
		mc_arrowDown:MovieClip;
	//mcUp和mcDown是buttonMode=true,有2真,_up,_over
	public function InitArrows(mcUp:MovieClip,mcDown:MovieClip,p_ScrollSpeed:Number=10){
		
		mc_arrowUp=mcUp;
		mc_arrowDown=mcDown;
		
		mcUp.buttonMode=true;
		mcDown.buttonMode=true;
		ScrollSpeed=p_ScrollSpeed;
		
		mcUp.gotoAndStop(1);
		mcDown.gotoAndStop(1);
		
		mcUp.addEventListener(MouseEvent.ROLL_OVER, moverHandler_Up);
		mcDown.addEventListener(MouseEvent.ROLL_OVER, moverHandler_Down);
		
		mcUp.addEventListener(MouseEvent.ROLL_OUT, moutHandler);
		mcDown.addEventListener(MouseEvent.ROLL_OUT, moutHandler);
	}
	private function moverHandler_Up(e:MouseEvent){
		iCurScrollSpeed=-ScrollSpeed;
		spr_c.addEventListener(Event.ENTER_FRAME, efh);
	}
	private function moverHandler_Down(e:MouseEvent){
		iCurScrollSpeed=ScrollSpeed;
		spr_c.addEventListener(Event.ENTER_FRAME, efh);
		
	}
	private function efh(e:Event){
		var h:Number=(mapH - rect.height);
		h=MathDG.C(h, rect.height,h);//因为mapH可能为0,10,20,会小于rect.height
		sb.setPercentImmediately(sb.getPercent()+iCurScrollSpeed/h);
	}
	private function moutHandler(e:MouseEvent){
		spr_c.removeEventListener(Event.ENTER_FRAME, efh);
	}
	
	//-----测试是否显示sliderBar,如果条不够长就不显示sb
	private function testShowSB(){
		if(mapH>rect.height){
			sb.getDO().visible=true;
			
			if(mc_arrowUp!=null
				&&mc_arrowDown!=null){
				mc_arrowUp.visible=true;
				mc_arrowDown.visible=true;
			}
			
		}else{
			sb.getDO().visible=false;
			
			if(mc_arrowUp!=null
				&&mc_arrowDown!=null){
				mc_arrowUp.visible=false;
				mc_arrowDown.visible=false;
			}
		}
	}
} //end of class
}
////////////////////////////////////////////////
/*
	//插入,在i之后插入,
	public function insert (k,elem){
		//T.p("smartList+insert"+k+" "+elem);
		//--------视图操作---------
		//Step 2: 其他东西先下移后插入，因为这里用到了size,要保证这时size不变
		for (var i = k + 1; i < size(); i ++){
			var mc : MovieClip = getElemMovieClip (v_Elem [i]);
			
			//mc._y=ElemH*(i+1);//不能直接移动到指定位置，因为初始化的时候是在缓动
			EffectManager.startMove(mc,0,ElemH*(i+1),K3);
		}
		
		//Step 3://插入
		//--控制视图里加上
		var mc : MovieClip = getElemMovieClip (elem);
		
		//mc._y=ElemH*(k+1);//不能直接移动到指定位置，因为初始化的时候是在缓动
		EffectManager.startMove(mc,0,ElemH*(k+1),K3);
		
		//Step 4:地图高度增加
		mapH += ElemH;
		//调整slider的长度
		SliderBar_changeSliderHeight (e_h, mapH);
		//Step5:焦点放在“主场景”
		
		//--------数据模型操作----------
		v_Elem.splice(k+1,0,elem);//(0,1,2,3)在1 插入6后是(0,6,1,2,3)
	}
	//*/